const DatabaseInterface = require('./db-interface');
const initSqlJs = require('sql.js');
const path = require('path');
const fs = require('fs');

class SQLiteService extends DatabaseInterface {
  constructor(config) {
    super(config);
    this.db = null;
    // 使用绝对路径确保一致性
    this.dbPath = path.resolve(config.dbPath || path.join(__dirname, '../server/warehouse.db'));
  }

  // 连接数据库
  async connect() {
    try {
      const SQL = await initSqlJs();
      
      // 确保数据库目录存在
      const dir = path.dirname(this.dbPath);
      if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
        console.log(`✅ 创建数据库目录: ${dir}`);
      }
      
      // 检查数据库文件是否存在
      if (fs.existsSync(this.dbPath)) {
        // 从文件加载数据库
        const fileBuffer = fs.readFileSync(this.dbPath);
        this.db = new SQL.Database(fileBuffer);
        console.log('✅ SQLite数据库已从文件加载');
      } else {
        // 创建新的数据库
        this.db = new SQL.Database();
        console.log('✅ 创建新的SQLite数据库');
        // 立即保存空数据库到文件
        this.saveDatabase();
      }
      
      // 初始化表结构
      await this.initSchema();
      
      // 默认从配置文件加载数据
      await this.loadDataFromConfig();
      
      return this.db;
    } catch (error) {
      console.error('SQLite数据库连接失败:', error);
      throw error;
    }
  }

  // 断开数据库连接
  async disconnect() {
    try {
      if (this.db) {
        // 在断开连接前保存数据库
        this.saveDatabase();
        this.db.close();
        this.db = null;
        console.log('✅ SQLite数据库连接已关闭');
      }
    } catch (error) {
      console.error('关闭SQLite数据库连接失败:', error);
    }
  }

  // 保存数据库到文件
  saveDatabase() {
    try {
      if (this.db) {
        console.log(`💾 开始保存SQLite数据库到文件: ${this.dbPath}`);
        const data = this.db.export();
        const buffer = Buffer.from(data);
        
        // 确保目录存在
        const dir = path.dirname(this.dbPath);
        if (!fs.existsSync(dir)) {
          fs.mkdirSync(dir, { recursive: true });
        }
        
        // 先写入临时文件，再重命名以确保原子性
        const tempPath = this.dbPath + '.tmp';
        fs.writeFileSync(tempPath, buffer);
        fs.renameSync(tempPath, this.dbPath);
        console.log('✅ SQLite数据库已保存到文件');
        
        // 验证文件是否正确保存
        const stats = fs.statSync(this.dbPath);
        console.log(`📄 数据库文件大小: ${stats.size} 字节`);
      }
    } catch (error) {
      console.error('保存SQLite数据库失败:', error);
      // 不抛出错误，避免影响主流程
    }
  }

  // 执行查询
  async query(sql, params = []) {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      console.log(`🔍 执行SQLite查询: ${sql}`, params);
      
      const stmt = this.db.prepare(sql);
      if (params && params.length > 0) {
        stmt.bind(params);
      }
      
      const rows = [];
      while (stmt.step()) {
        rows.push(stmt.getAsObject());
      }
      
      console.log(`📊 SQLite查询结果: ${rows.length} 条记录`);
      return rows;
    } catch (error) {
      console.error('SQLite查询失败:', error);
      throw error;
    }
  }

  // 执行插入
  async insert(sql, params = []) {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      console.log(`➕ 执行SQLite插入: ${sql}`, params);
      
      const stmt = this.db.prepare(sql);
      const result = stmt.run(params);
      
      // 保存数据库
      this.saveDatabase();
      
      console.log(`✅ SQLite插入完成，更改行数: ${result.changes}`);
      return result;
    } catch (error) {
      console.error('SQLite插入失败:', error);
      throw error;
    }
  }

  // 执行更新
  async update(sql, params = []) {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      console.log(`✏️  执行SQLite更新: ${sql}`, params);
      
      const stmt = this.db.prepare(sql);
      const result = stmt.run(params);
      
      // 保存数据库
      this.saveDatabase();
      
      console.log(`✅ SQLite更新完成，更改行数: ${result.changes}`);
      return result;
    } catch (error) {
      console.error('SQLite更新失败:', error);
      throw error;
    }
  }

  // 执行删除
  async delete(sql, params = []) {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      console.log(`➖ 执行SQLite删除: ${sql}`, params);
      
      const stmt = this.db.prepare(sql);
      const result = stmt.run(params);
      
      // 保存数据库
      this.saveDatabase();
      
      console.log(`✅ SQLite删除完成，更改行数: ${result.changes}`);
      return result;
    } catch (error) {
      console.error('SQLite删除失败:', error);
      throw error;
    }
  }

  // 执行事务
  async executeTransaction(operations) {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      console.log(`🔄 执行SQLite事务，操作数: ${operations.length}`);
      
      // 开始事务
      this.db.run("BEGIN TRANSACTION;");
      
      let changes = 0;
      for (const operation of operations) {
        const stmt = this.db.prepare(operation.sql);
        const result = stmt.run(operation.params || []);
        changes += result.changes;
        console.log(`  ✅ 执行操作: ${operation.type}`, operation.sql);
      }
      
      // 提交事务
      this.db.run("COMMIT;");
      
      // 保存数据库
      this.saveDatabase();
      
      console.log(`✅ SQLite事务执行完成，总更改行数: ${changes}`);
      return { success: true, changes };
    } catch (error) {
      // 回滚事务
      try {
        this.db.run("ROLLBACK;");
      } catch (rollbackError) {
        console.error('事务回滚失败:', rollbackError);
      }
      
      console.error('SQLite事务执行失败:', error);
      throw error;
    }
  }

  // 执行事务（实现接口方法）
  async transaction(operations) {
    return await this.executeTransaction(operations);
  }

  // 初始化表结构
  async initSchema() {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      // 从统一的初始化脚本加载表结构
      const initSchemaPath = path.join(__dirname, '../database/init-schema.sql');
      if (fs.existsSync(initSchemaPath)) {
        console.log('🔍 使用统一初始化脚本初始化数据库结构...');
        const initSchema = fs.readFileSync(initSchemaPath, 'utf8');
        // 使用更智能的方式分割SQL语句，避免在触发器中分割
        const statements = this.splitSQLStatements(initSchema);
        for (const statement of statements) {
          if (statement.trim() !== '') {
            try {
              this.db.run(statement);
            } catch (stmtError) {
              console.warn('⚠️ SQL语句执行失败:', stmtError.message);
              console.warn('  语句:', statement.substring(0, 100) + '...');
            }
          }
        }
        console.log('✅ 数据库结构初始化完成');
      } else {
        console.error('❌ 统一初始化脚本未找到:', initSchemaPath);
        throw new Error('数据库结构初始化脚本未找到');
      }
      
      // 从单独的SQL文件加载审计表和触发器定义
      const auditSchemaPath = path.join(__dirname, '../server/audit-schema.sql');
      if (fs.existsSync(auditSchemaPath)) {
        console.log('🔍 加载审计表和触发器定义...');
        const auditSchema = fs.readFileSync(auditSchemaPath, 'utf8');
        // 使用更智能的方式分割SQL语句，避免在触发器中分割
        const statements = this.splitSQLStatements(auditSchema);
        for (const statement of statements) {
          if (statement.trim() !== '') {
            try {
              this.db.run(statement);
            } catch (stmtError) {
              console.warn('⚠️ 审计SQL语句执行失败:', stmtError.message);
              console.warn('  语句:', statement.substring(0, 100) + '...');
            }
          }
        }
        console.log('✅ 审计表和触发器初始化完成');
      } else {
        console.warn('⚠️ 审计模式文件未找到:', auditSchemaPath);
      }
      
      console.log('✅ SQLite数据库表结构初始化完成');
      // 保存表结构到文件
      this.saveDatabase();
    } catch (error) {
      console.error('SQLite数据库表结构初始化失败:', error);
      throw error;
    }
  }

  // 智能分割SQL语句，避免在触发器中错误分割
  splitSQLStatements(sql) {
    const statements = [];
    let currentStatement = '';
    let inTrigger = false;
    const lines = sql.split('\n');
    
    for (const line of lines) {
      // 检查是否进入触发器定义
      if (line.trim().toUpperCase().startsWith('CREATE TRIGGER')) {
        inTrigger = true;
      }
      
      // 添加当前行到语句中
      currentStatement += line + '\n';
      
      // 检查是否结束触发器定义
      if (inTrigger && line.trim().toUpperCase() === 'END;') {
        inTrigger = false;
        // 触发器定义完整，添加到语句列表中
        statements.push(currentStatement.trim());
        currentStatement = '';
      }
      
      // 如果不在触发器中且行以分号结尾，则认为是一个完整语句
      if (!inTrigger && line.trim().endsWith(';')) {
        statements.push(currentStatement.trim());
        currentStatement = '';
      }
    }
    
    // 添加剩余的语句（如果有）
    if (currentStatement.trim() !== '') {
      statements.push(currentStatement.trim());
    }
    
    return statements;
  }

  // 从配置文件加载数据
  async loadDataFromConfig() {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      console.log('🔍 从配置文件加载数据...');
      
      // 加载仓库配置数据
      const warehouseConfigPath = path.join(__dirname, '../public/warehouse-config.json');
      if (fs.existsSync(warehouseConfigPath)) {
        const warehouseConfig = JSON.parse(fs.readFileSync(warehouseConfigPath, 'utf8'));
        console.log('📊 仓库配置:', warehouseConfig);
        
        // 先检查storage_slots表是否已有数据
        const existingSlots = await this.query('SELECT COUNT(*) as count FROM storage_slots');
        const slotCount = existingSlots[0]?.count || 0;
        
        if (slotCount > 0) {
          console.log(`ℹ️ storage_slots表已有 ${slotCount} 条数据，跳过货位自动创建`);
          return; // 已有数据，直接返回，避免重复插入
        }
        
        // 根据配置创建货位（仅在表为空时执行）
        const { rows, columns, layers } = warehouseConfig;
        const totalSlots = rows * columns * layers;
        console.log(`🏗️  准备创建 ${totalSlots} 个货位 (${rows}行 × ${columns}列 × ${layers}层)`);
        
        // 创建事务来批量插入货位
        const operations = [];
        let slotId = 1; // 自然数ID计数器
        for (let layer = 1; layer <= layers; layer++) {
          for (let row = 1; row <= rows; row++) {
            for (let col = 1; col <= columns; col++) {
              const createdAt = new Date().toISOString();
              operations.push({
                type: 'INSERT_SLOT',
                sql: `INSERT OR IGNORE INTO storage_slots (id, layer, row, column, has_goods, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)`,
                params: [slotId, layer, row, col, 0, createdAt, createdAt]
              });
              slotId++;
            }
          }
        }
        
        if (operations.length > 0) {
          await this.executeTransaction(operations);
          console.log(`✅ 成功创建 ${operations.length} 个货位`);
        }
      } else {
        console.log('⚠️ 仓库配置文件未找到，跳过数据初始化');
      }
      
      // 可以在这里添加更多从配置文件加载数据的逻辑
      // 例如加载PLC配置、任务配置等
      
    } catch (error) {
      console.error('从配置文件加载数据失败:', error);
      // 不抛出错误，避免影响主流程
    }
  }

  // 从init-data.sql文件加载数据（手动选择时调用）
  async loadDataFromScript() {
    try {
      if (!this.db) {
        throw new Error('数据库未连接');
      }
      
      
        console.log('🔍 加载初始数据脚本...');
        const initData = fs.readFileSync(initDataPath, 'utf8');
        // 分割SQL语句并逐个执行
        const statements = initData.split(';').filter(stmt => stmt.trim() !== '');
        let executedCount = 0;
        for (const statement of statements) {
          if (statement.trim() !== '') {
            try {
              this.db.run(statement);
              executedCount++;
            } catch (stmtError) {
              console.warn('⚠️ 数据初始化语句执行失败:', stmtError.message);
              console.warn('  语句:', statement.substring(0, 100) + '...');
            }
          }
        }
        console.log(`✅ 初始数据加载完成，执行了 ${executedCount} 条语句`);
      
    } catch (error) {
      console.error('SQLite数据库初始数据加载失败:', error);
      // 不抛出错误，避免影响主流程
    }
  }
}

module.exports = SQLiteService;
























